#version 460 core

#define M_PI 3.1415926535897932384626433832795

layout(location = 0) out vec4 FragColor;

in vec3 FragPos;
in vec2 TexCoord;
in vec3 Normal;
in vec3 Tangent;
in vec3 Bitangent;

uniform int mode;
uniform int area;
uniform int tex_h;
uniform int tex_w;
uniform vec3 view_pos;

layout(rgba32f, binding = 0) uniform image2D world_pos_map;
layout(rgba32f, binding = 1) uniform image2D radiance_map;

layout(binding = 0) uniform sampler2D diffuse;
layout(binding = 1) uniform sampler2D normal;
// layout(binding = 31) uniform sampler2D radiance_map_after_sss;

float fDiffuseProfile(float r, float A, float s) // A = 0.1, s = 3.78
{
	return A * s * ( ( exp(-s * r) + exp(-s * r / 3) ) / (8 * M_PI * r) );
}

void main()
{
	int light_n = 1;
	vec3 light_dir[1] = {normalize(vec3(1.0, 1.0, 1.0))};
	vec3 light_color[1] = {vec3(1, 1, 1)};
	vec3 lighting = vec3(0, 0, 0);
	vec3 normal_ts = texture(normal, TexCoord).xyz * 2 - 1;
	vec3 normal = normalize(normal_ts.x * Tangent + normal_ts.y * Bitangent + normal_ts.z * Normal);
	for (int i = 0; i < light_n; i++)
	{
		lighting += max(dot(normal, light_dir[i]), 0.0) * light_color[i] * texture(diffuse, TexCoord).rgb;
	}
	if (mode == 0)
		;
	else if (mode == 1)
	{
		// sss
		vec3 sss_color = vec3(0);
		int ccol = int(TexCoord.x * tex_w);
		int crow = int(TexCoord.y * tex_h);
		vec3 cpos = imageLoad(world_pos_map, ivec2(ccol, crow)).xyz;
		for (int row = 0; row < tex_h; row++)
		{
			for (int col = 0; col < tex_w; col++)
			{
				vec3 pos = imageLoad(world_pos_map, ivec2(col, row)).xyz;
				float l = length(pos - cpos);
				if (l > 0)
				{
					vec3 radiance = imageLoad(radiance_map, ivec2(col, row)).rgb;
					sss_color += fDiffuseProfile(l, 1.0, 0.05) * radiance;
				}
			}
		}
		sss_color /= tex_h * tex_w;
		lighting += texture(diffuse, TexCoord).rgb * sss_color;
	}

	FragColor = vec4(lighting, 1.0);
}
